#include <stdio.h>
#include "driver/adc.h"
#include "app.h"
#include "kalman_filter.h"
#include "driver/timer.h"

extern tSys_Flag Sys_Flag;
extern tSys_Status Sys_Status;

//#define ADC_MODE 




//////////////////////////////////////////  ADC  方式  //////////////////////////////////////////////////
// 定义ADC配置
 #define ADC_CHANNEL ADC1_CHANNEL_3  // 使用ADC1通道3（GPIO VN）
 #define ADC_ATTEN ADC_ATTEN_DB_11   // 设置衰减器为11dB（量程为0-3.3V）
 #define ADC_WIDTH ADC_WIDTH_BIT_12  // 12 位精度


void adc_init() {
    adc1_config_width(ADC_WIDTH);
    adc1_config_channel_atten(ADC_CHANNEL, ADC_ATTEN);
}

// 读取ADC值（单次转换）
int read_adc_value() {
    return adc1_get_raw(ADC_CHANNEL);  // 触发单次转换并读取原始ADC值
}


/////////////////////////////////////////  GPIO  方式 /////////////////////////////////////////////////
#define GPIO_INPUT_PIN GPIO_NUM_36  // 输入信号连接的GPIO引脚

static uint32_t rise_time = 0;  // 上升沿时间戳
static uint32_t fall_time = 0;  // 下降沿时间戳
static bool is_high = false;    // 当前信号状态

static uint32_t data_buff[12] = { 0 } ;
static uint8_t data_cont = 0 ;
static uint32_t clean_data_time = 0;
// GPIO中断处理函数
static void IRAM_ATTR gpio_isr_handler(void *arg)
{
    uint32_t current_time = esp_timer_get_time(); // 获取当前时间（微秒）
    uint32_t temp_time = 0;

    if (gpio_get_level(GPIO_INPUT_PIN) == 1)
    { // 上升沿
        rise_time = current_time;
        is_high = true;
    }
    else
    { // 下降沿
        fall_time = current_time;
        is_high = false;

        temp_time = fall_time - rise_time;
        if( temp_time > 1000000 )   // 时间间隔超过了1秒
        {
            data_cont = 0;
        }
        else
        {
           data_buff[data_cont++] = temp_time; 
        }
        
        if (data_cont > 9)
        {
            data_cont = 0;
            data_buff[10] = 0;
            // 计算脉冲宽度
            for (uint8_t i = 0; i < 10; i++)
            {
                data_buff[10] += data_buff[i];
            }
            data_buff[11] = data_buff[10] / 10;
        }
    }

    clean_data_time = 0;
}

void  Gpio_Init(void)
{
    // 配置GPIO引脚
    gpio_config_t io_conf = {
        .pin_bit_mask = (1ULL << GPIO_INPUT_PIN),
        .mode = GPIO_MODE_INPUT,
        .pull_up_en = GPIO_PULLUP_DISABLE,
        .pull_down_en = GPIO_PULLDOWN_ENABLE,
        .intr_type = GPIO_INTR_ANYEDGE,  // 上升沿和下降沿都触发中断
    };
    gpio_config(&io_conf);

    // 安装GPIO中断服务
    gpio_install_isr_service(ESP_INTR_FLAG_LEVEL1);
    gpio_isr_handler_add(GPIO_INPUT_PIN, gpio_isr_handler, NULL);
}

// 读取ADC数据

void Adc_Task(void *args)
{
    uint32_t ret_num = 0;
    KalmanFilter kf ,kf_Temp;
    int temp_cont = 0;
// 模拟一些测量数据
    //float measurements[] = {1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0};
    Gpio_Init();
    kalman_init(&kf, 0.01, 0.1, 0, 1); // 参数需要根据实际应用调整
    kalman_init(&kf_Temp, 0.01, 0.1, 0, 1); // 参数需要根据实际应用调整
    adc_init();
   
    while (1)
    {
        if (ret_num != data_buff[11])
        {
            ret_num = data_buff[11];
            float filtered_value = kalman_update(&kf, data_buff[11]);
            Sys_Status.Current_Value = (int )filtered_value ;
           // ESP_LOGI("ADC", "Sys_Status.Current_Value =  %d , data_buff[11] = %d  data_buff[0] = %ddata_buff[1] = %ddata_buff[10] = %d", 
           // (int)Sys_Status.Current_Value ,(int) data_buff[11],(int) data_buff[0] ,(int) data_buff[1] ,(int) data_buff[10] );
        }
        
        if(temp_cont > 100) // 1秒采集一次温度
        {
            temp_cont = 0;
            float filtered_temp_value = kalman_update(&kf_Temp, read_adc_value());
            Sys_Status.Temp_Adc_Value = filtered_temp_value;
          //  ESP_LOGI("ADC" , " Sys_Status.Temp_Adc_Value = %d" ,  (int )Sys_Status.Temp_Adc_Value);
        }
        else
            temp_cont++;
        

        

        if(clean_data_time > 500)
        {
            if(  Sys_Status.Current_Value != 0)
            {
                Sys_Status.Current_Value = 0; data_buff[11] = 0;
            }
        }
        else
        {
            clean_data_time++;
        }

        vTaskDelay(10); // 延时1ms秒
        //vTaskDelay(1000); // 延时1ms秒
    }
}
    